//! 变量绑定示例
//!
//! 在 Rust 中，变量默认是不可变的。当我们创建一个变量时，我们说我们在"绑定"一个值到一个名称上。
//! 变量绑定通过 let 关键字实现。

/// 基础变量绑定
///
/// 展示变量绑定的基本概念和用法
pub fn basic_bindings() {
    println!("=== 基础变量绑定 ===");

    // 不可变绑定（默认）
    let x = 5;
    println!("x 的值是: {}", x);

    // 可变绑定
    let mut y = 10;
    println!("y 的初始值是: {}", y);
    y = 15;
    println!("y 的新值是: {}", y);

    // 变量遮蔽（Shadowing）
    let z = 100;
    println!("z 的初始值是: {}", z);

    let z = z + 10; // 这里我们创建了一个新变量 z，遮蔽了之前的 z
    println!("z 遮蔽后的值是: {}", z);

    let z = "现在 z 是一个字符串";
    println!("z 再次遮蔽后的值是: {}", z);
}

/// 变量绑定与模式匹配
///
/// let 语句实际上是模式匹配的一种形式
pub fn bindings_with_patterns() {
    println!("\n=== 变量绑定与模式匹配 ===");

    // 元组解构
    let (a, b, c) = (1, 2, 3);
    println!("解构元组: a={}, b={}, c={}", a, b, c);

    // 结构体解构
    struct Point {
        x: i32,
        y: i32,
    }

    let point = Point { x: 10, y: 20 };
    let Point { x, y } = point;
    println!("解构结构体: x={}, y={}", x, y);

    // 带字段重命名的结构体解构
    let point = Point { x: 30, y: 40 };
    let Point { x: x_val, y: y_val } = point;
    println!("解构并重命名: x_val={}, y_val={}", x_val, y_val);

    // 部分解构
    let point = Point { x: 50, y: 60 };
    let Point { x, .. } = point; // 只关心 x 字段
    println!("部分解构，只获取 x: {}", x);
}

/// 变量绑定中的类型注解
///
/// 在变量绑定时可以显式指定类型
pub fn type_annotations() {
    println!("\n=== 变量绑定中的类型注解 ===");

    // 显式类型注解
    let a: i32 = 5;
    let b: f64 = 1.21;
    let c: char = 'R';
    let d: &str = "Hello";

    println!("类型注解示例: a={}, b={}, c={}, d={}", a, b, c, d);

    // 在复杂类型中使用类型注解
    let numbers: Vec<i32> = Vec::new();
    println!("空向量: {:?}", numbers);

    // 使用类型注解消除歧义
    let mut map: std::collections::HashMap<i32, String> = std::collections::HashMap::new();
    map.insert(1, String::from("one"));
    println!("HashMap: {:?}", map);
}

/// 变量绑定与 mut 关键字
///
/// mut 关键字控制变量的可变性
pub fn mutability() {
    println!("\n=== 变量绑定与 mut 关键字 ===");

    // 不可变变量
    let x = 5;
    // x = 6; // 这会导致编译错误

    // 可变变量
    let mut y = 10;
    println!("y 的初始值: {}", y);
    y = 15; // 这是允许的
    println!("y 的新值: {}", y);

    // 可变引用
    let mut z = 20;
    let r = &mut z; // r 是 z 的可变引用
    *r += 1; // 通过解引用修改 z 的值
    println!("通过可变引用修改后 z 的值: {}", z);

    // 重新绑定
    let w = 30;
    println!("w 的值: {}", w);
    let w = 40; // 这不是修改，而是重新绑定
    println!("重新绑定后 w 的值: {}", w);
}

/// 变量绑定与作用域
///
/// 变量绑定有特定的作用域范围
pub fn scope_and_shadowing() {
    println!("\n=== 变量绑定与作用域 ===");

    let x = 5;
    println!("外层作用域中的 x: {}", x);

    {
        // 这里的 x 遮蔽了外层的 x
        let x = 10;
        println!("内层作用域中的 x: {}", x);

        let y = 15;
        println!("内层作用域中的 y: {}", y);
    } // y 在这里超出作用域

    // x 又变回 5
    println!("回到外层作用域中的 x: {}", x);
    // println!("y: {}", y); // 这会导致编译错误，因为 y 已超出作用域
}

/// 高级变量绑定技巧
///
/// 展示一些高级的变量绑定用法
pub fn advanced_bindings() {
    println!("\n=== 高级变量绑定技巧 ===");

    // 在 if let 中使用变量绑定
    let some_option = Some(5);
    if let Some(value) = some_option {
        println!("从 Option 中获取值: {}", value);
    }

    // 在 while let 中使用变量绑定
    let mut counter = Some(0);
    while let Some(i) = counter {
        if i > 3 {
            counter = None;
        } else {
            println!("计数器: {}", i);
            counter = Some(i + 1);
        }
    }

    // 在 match 中使用变量绑定
    enum Message {
        Quit,
        Move { x: i32, y: i32 },
        Write(String),
    }

    let msg = Message::Move { x: 10, y: 20 };
    match msg {
        Message::Quit => println!("退出消息"),
        Message::Move { x, y } => println!("移动消息: x={}, y={}", x, y),
        Message::Write(text) => println!("文本消息: {}", text),
    }

    // 使用下划线忽略不需要的值
    let (_, second, _) = (1, 2, 3);
    println!("只关心第二个值: {}", second);

    // 使用 .. 忽略剩余值
    struct Data {
        important: i32,
        unimportant1: i32,
        unimportant2: i32,
        unimportant3: i32,
    }

    let data = Data {
        important: 42,
        unimportant1: 1,
        unimportant2: 2,
        unimportant3: 3,
    };

    let Data { important, .. } = data;
    println!("重要数据: {}", important);
}

/// 主演示函数
pub fn demonstrate_variable_bindings() {
    basic_bindings();
    bindings_with_patterns();
    type_annotations();
    mutability();
    scope_and_shadowing();
    advanced_bindings();
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_basic_bindings() {
        basic_bindings();
    }

    #[test]
    fn test_bindings_with_patterns() {
        bindings_with_patterns();
    }

    #[test]
    fn test_type_annotations() {
        type_annotations();
    }

    #[test]
    fn test_mutability() {
        mutability();
    }

    #[test]
    fn test_scope_and_shadowing() {
        scope_and_shadowing();
    }

    #[test]
    fn test_advanced_bindings() {
        advanced_bindings();
    }
}
